
local U = require "packages/hanqing/util"

local gujie = fk.CreateSkill{
  name = "hanqing__gujie",
  tags = { U.Reform },
}

Fk:loadTranslationTable{
  ["hanqing__gujie"] = "辜诫",
  [":hanqing__gujie"] = "<a href='hanqing_reform_skill'>变革技</a>，游戏开始时，你依次将五种不同<a href=':hanqing__precept'>《戒律》</a>"..
  "置入你的装备区；<a href=':hanqing__precept'>《戒律》</a>移出游戏时，你可以改为将其置入另一名角色装备栏并替换其原有装备。",

  ["#hanqing__gujie-choose"] = "辜诫：《%arg》（%arg2）即将移出游戏，你可以将之置入另一名角色的装备栏",

  ["precept"] = "戒律",
  ["hanqing__precept"] = "戒律",
  [":hanqing__precept"] = "《戒律》共有五种：<br>"..
  "<a href=':propriety__precept'>《礼戒·愚律》</a><br>"..
  "<a href=':righteousness__precept'>《义戒·弱律》</a><br>"..
  "<a href=':benevolence__precept'>《仁戒·贫律》</a><br>"..
  "<a href=':wisdom__precept'>《智戒·疲律》</a><br>"..
  "<a href=':integrity__precept'>《信戒·辱律》</a>",
}

local precepts = {
  "propriety__precept",
  "righteousness__precept",
  "benevolence__precept",
  "wisdom__precept",
  "integrity__precept",
}

gujie:addEffect(fk.GameStart, {
  anim_type = "drawcard",
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(gujie.name) and
      table.find(player.room:getBanner(gujie.name), function (id)
        return player.room:getCardArea(id) == Card.Void and
          player:canMoveCardIntoEquip(id, true)
      end)
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    for _, id in ipairs(room:getBanner(gujie.name)) do
      if player.dead then return end
      if room:getCardArea(id) == Card.Void and player:canMoveCardIntoEquip(id, true) then
        room:moveCardIntoEquip(player, id, gujie.name, true, player)
      end
    end
  end,
})

gujie:addEffect(fk.BeforeCardsMove, {
  anim_type = "offensive",
  can_trigger = function (self, event, target, player, data)
    if player:hasSkill(gujie.name) then
      for _, move in ipairs(data) do
        if move.from and move.toArea == Card.Void then
          for _, info in ipairs(move.moveInfo) do
            if info.fromArea == Card.PlayerEquip and
              table.contains(precepts , Fk:getCardById(info.cardId).name) and
              table.find(player.room:getOtherPlayers(move.from, false), function (p)
                return #p:getAvailableEquipSlots(Fk:getCardById(info.cardId).sub_type) > 0
              end) then
              return true
            end
          end
        end
      end
    end
  end,
  on_trigger = function (self, event, target, player, data)
    local room = player.room
    local dat = {}
    for _, move in ipairs(data) do
      if move.from and move.toArea == Card.Void then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerEquip and
            table.contains(precepts , Fk:getCardById(info.cardId).name) then
            table.insert(dat, {move.from, info.cardId})
          end
        end
      end
    end
    for _, d in ipairs(dat) do
      if not player:hasSkill(gujie.name) then return end
      if table.find(data, function (move)
        return move.from == d[1] and
          table.find(move.moveInfo, function (info)
            return info.cardId == d[2] and info.fromArea == Card.PlayerEquip
          end) ~= nil and
          table.find(room:getOtherPlayers(move.from, false), function (p)
            return p:canMoveCardIntoEquip(d[2], true)
          end) ~= nil
      end) then
        event:setCostData(self, {extra_data = d})
        self:doCost(event, target, player, data)
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local dat = event:getCostData(self).extra_data
    local targets = table.filter(room:getOtherPlayers(dat[1], false), function (p)
      return p:canMoveCardIntoEquip(dat[2], true)
    end)
    local to = room:askToChoosePlayers(player, {
      min_num = 1,
      max_num = 1,
      targets = targets,
      skill_name = gujie.name,
      prompt = "#hanqing__gujie-choose:::"..Fk:getCardById(dat[2]).name..":"..Fk:getCardById(dat[2]):getSubtypeString(),
      cancelable = true,
    })
    if #to > 0 then
      event:setCostData(self, {tos = to, id = dat[2]})
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local to = event:getCostData(self).tos[1]
    local id = event:getCostData(self).id
    local new_data = {}
    for _, move in ipairs(data) do
      local new_move = {}
      if #move.moveInfo > 0 and move.toArea == Card.Void then
        local orig_info, new_info = {}, {}
        for i = 1, #move.moveInfo do
          local info = move.moveInfo[i]
          local will_destruct = false
          if info.fromArea == Card.PlayerEquip and info.cardId == id then
            will_destruct = true
          end
          if will_destruct then
            table.insert(new_info, info)
          else
            table.insert(orig_info, info)
          end
        end
        move.moveInfo = orig_info
        if #new_info > 0 then
          new_move = {
            moveInfo = new_info,
            from = move.from,
            to = to,
            toArea = Card.PlayerEquip,
            moveReason = fk.ReasonPut,
            proposer = player,
            skillName = gujie.name,
            moveVisible = true,
          }
          if not to:hasEmptyEquipSlot(Fk:getCardById(id).sub_type) then
            local existingEquip = to:getEquipments(Fk:getCardById(id).sub_type)
            local throw = #existingEquip == 1 and existingEquip[1] or
            room:askToChooseCard(player, {
              target = to,
              flag = { card_data = { { Util.convertSubtypeAndEquipSlot(Fk:getCardById(id).sub_type), existingEquip } } },
              skill_name = "replaceEquip",
              prompt = "#replaceEquip",
            })
            table.insert(data, {
              ids = { throw },
              from = move.from,
              fromArea = Card.PlayerEquip,
              toArea = Card.DiscardPile,
              moveReason = fk.ReasonPutIntoDiscardPile,
              skillName = gujie.name,
              proposer = player,
              moveInfo = {{
                cardId = throw,
                fromArea = Card.PlayerEquip,
              }},
            })
          end
        end
      end
      if next(new_move) then
        table.insert(new_data, new_move)
      end
    end
    if next(new_data) then
      table.insertTable(data, new_data)
    end
  end,
})

gujie:addAcquireEffect(function (self, player, is_start)
  local room = player.room
  if not room:getBanner(gujie.name) then
    local cards = {}
    for _, name in ipairs(precepts) do
      local card = room:printCard(name)  ---@type EquipCard
      room:addSkill(card.equip_skill)
      table.insert(cards, card.id)
    end
    room:setBanner(gujie.name, cards)
  end
end)

return gujie
